package com.xuan.yupao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuan.yupao.common.ErrorCode;
import com.xuan.yupao.exception.BusinessException;
import com.xuan.yupao.model.domain.AddRequest;
import com.xuan.yupao.model.domain.Friend;
import com.xuan.yupao.model.domain.User;
import com.xuan.yupao.model.domain.vo.AddRequestVo;
import com.xuan.yupao.model.domain.vo.UserVo;
import com.xuan.yupao.service.AddRequestService;
import com.xuan.yupao.service.FriendService;
import com.xuan.yupao.mapper.FriendMapper;
import com.xuan.yupao.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* @author 清凉茶
* @description 针对表【friend(好友表)】的数据库操作Service实现
* @createDate 2024-07-08 19:52:47
*/
@Service
public class FriendServiceImpl extends ServiceImpl<FriendMapper, Friend>
    implements FriendService{

    @Resource
    private AddRequestService addRequestService;

    @Resource
    private UserService userService;

    @Override
    public String addFriend(Long fromId, Long toId, String requestMessage) {
        // 1. 查看是否已经是好友,是则抛出异常
        checkIsFriend(fromId, toId);

        // 2. 查看是否是否存在未处理的好友申请
        // 存在则修改申请内容,否则插入新的记录
        QueryWrapper<AddRequest> addRequestQueryWrapper = new QueryWrapper<>();
        addRequestQueryWrapper.eq("from_id", fromId).eq("to_id", toId);
        addRequestQueryWrapper.eq("status", 0);
        AddRequest addRequest = addRequestService.getOne(addRequestQueryWrapper);
        if (addRequest != null) {
            // 更新申请内容
            UpdateWrapper<AddRequest> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", addRequest.getId());
            updateWrapper.set(requestMessage != null, "request_message", requestMessage);
            boolean update = addRequestService.update(updateWrapper);
            if (!update) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "更新申请信息失败");
            }
        } else {
            // 插入新的记录
            AddRequest insertAddRequest = new AddRequest();
            insertAddRequest.setFromId(fromId);
            insertAddRequest.setToId(toId);
            if (requestMessage != null) {
                insertAddRequest.setRequestMessage(requestMessage);
            }
            boolean save = addRequestService.save(insertAddRequest);
            if (!save) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "添加好友申请失败");
            }
        }
        return "好友申请发送成功!";
    }

    @Override
    @Transactional
    public String agreeFriendApply(Long fromId, Long toId) {
        // 1. 查看是否已经是好友,是则抛出异常
        checkIsFriend(fromId, toId);

        // 2. 查看好友申请是否存在
        QueryWrapper<AddRequest> addRequestQueryWrapper = new QueryWrapper<>();
        addRequestQueryWrapper.eq("from_id", fromId).eq("to_id", toId);
        addRequestQueryWrapper.eq("status", 0);
        AddRequest addRequest = addRequestService.getOne(addRequestQueryWrapper);
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "好友申请不存在,添加好友失败");
        }

        // 3. 修改好友申请状态为 1 并往好友表中插入记录
        addRequest.setStatus(1);
        boolean b = addRequestService.updateById(addRequest);
        if (!b) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改好友申请状态失败");
        }
        // 往好友关系表插入数据 (操作失败则抛出异常)
        addFriendRecord(fromId, toId);
        addFriendRecord(toId, fromId);
        return "成功添加好友";
    }

    @Override
    public String refuseFriendApply(Long fromId, Long toId) {
        // 1. 查看是否已经是好友,是则抛出异常
        checkIsFriend(fromId, toId);

        // 2. 查看好友申请是否存在
        QueryWrapper<AddRequest> addRequestQueryWrapper = new QueryWrapper<>();
        addRequestQueryWrapper.eq("from_id", fromId).eq("to_id", toId);
        addRequestQueryWrapper.eq("status", 0);
        AddRequest addRequest = addRequestService.getOne(addRequestQueryWrapper);
        if (addRequest == null) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "好友申请不存在");
        }
        // 3. 修改好友申请状态为 2 并往好友表中插入记录
        addRequest.setStatus(2);
        boolean b = addRequestService.updateById(addRequest);
        if (!b) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "修改好友申请状态失败");
        }
        return "ok";
    }

    @Override
    public Long getFriendRequestNum(Long toId) {
        QueryWrapper<AddRequest> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("to_id", toId);
        queryWrapper.eq("status", 0);
        return addRequestService.count(queryWrapper);
    }

    @Override
    public List<AddRequestVo> getUntreatedRecords(Long toId) {
        // 1. 查询未处理的好友请求,并按 fromId 分类
        QueryWrapper<AddRequest> addRequestQueryWrapper = new QueryWrapper<>();
        addRequestQueryWrapper.eq("to_id", toId);
        List<AddRequest> addRequestList = addRequestService.list(addRequestQueryWrapper);
        // 没有好友申请直接返回
        if (CollectionUtils.isEmpty(addRequestList)) {
            return new ArrayList<>();
        }
        Map<Long, List<AddRequest>> addRequestMap = addRequestList.stream().collect(Collectors.groupingBy(AddRequest::getFromId));
        // 2. 获取好友申请发起方的用户信息,并按 userId 分类
        List<Long> userIdList = addRequestList.stream().map(AddRequest::getFromId).collect(Collectors.toList());
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", userIdList);
        Map<Long, List<User>> userMap = userService.list(userQueryWrapper).stream().collect(Collectors.groupingBy(User::getId));
        // 3. 返回好友请求信息(脱敏)
        return userIdList.stream().map(userId -> {
            AddRequestVo addRequestVo = new AddRequestVo();
            BeanUtils.copyProperties(addRequestMap.get(userId).get(0), addRequestVo);
            BeanUtils.copyProperties(userMap.get(userId).get(0), addRequestVo);
            return addRequestVo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<UserVo> getMyFriendList(Long userId) {
        QueryWrapper<Friend> friendQueryWrapper = new QueryWrapper<>();
        friendQueryWrapper.eq("user_id", userId);
        List<Long> friendIdList = this.list(friendQueryWrapper).stream().map(Friend::getFriendId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(friendIdList)) {
            return new ArrayList<>();
        }

        // 查询好友的详细信息(脱敏)
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.in("id", friendIdList);
        return userService.list(userQueryWrapper).stream().map(user -> userService.getSafetyUser(user)).collect(Collectors.toList());
    }


    private void checkIsFriend(Long userId, Long friendId) {
        QueryWrapper<Friend> friendQueryWrapper = new QueryWrapper<>();
        friendQueryWrapper.eq("user_id", userId).eq("friend_id", friendId);
        long count1 = this.count(friendQueryWrapper);
        friendQueryWrapper = new QueryWrapper<>();
        friendQueryWrapper.eq("user_id", friendId).eq("friend_id", userId);
        long count2 = this.count(friendQueryWrapper);
        if (count1 > 0 && count2 > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "已是好友关系,添加失败");
        }
    }

    private void addFriendRecord(Long userId, Long friendId) {
        Friend friend = new Friend();
        friend.setUserId(userId);
        friend.setFriendId(friendId);
        boolean b = this.save(friend);
        if (!b) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "新增好友关系失败");
        }
    }
}




